import { getPageMeta } from '@/services/request/meta';
import {
  formatForArrayTable,
  initialSchema,
  initialSchemaType,
} from '@/components/schema-form-render/utils';
import { triggerTableCellRender } from '@/biz-components/modals/triggerPlugin';
import { useCallback, useEffect, useState } from 'react';

import { TableColumnProps } from 'antd';

import { ISchema } from '@formily/react';

import { cloneDeep } from 'lodash';

import { DynamicObjectAny } from '@/typings';

interface PageMetaConfigData {
  initLoading: boolean;
  jsonSchema: ISchema;
  columns: TableColumnProps<any>[];
}

export const useSearchMeta = (formCode: string) => {
  const [loading, setLoading] = useState<boolean>(true);
  const [jsonSchema, setJsonSchema] = useState({});
  const [tableButtons, setTableButtons] = useState([]);
  const [tableColumns, setTableColumns] = useState([]);
  const [operationButton, setOperationButton] = useState([]);
  const fetchMeta = useCallback(() => {
    getPageMeta(formCode)
      .then((res: any) => {
        const { result } = res;
        const { schema, tableButtons: tableBtn, buttons, tableColumns: columns } = initialSchema(
          cloneDeep(result),
          'SEARCH',
        ) as any;
        setJsonSchema(schema);

        setTableButtons(tableBtn);
        setTableColumns(columns);

        setOperationButton(buttons || []);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [formCode]);

  useEffect(() => {
    if (formCode) {
      fetchMeta();
    }
  }, [formCode]);

  return {
    loading,
    schema: jsonSchema,
    tableButtons,
    tableColumns,
    operationButton,
  };
};

interface NormalMetaReturn {
  loading: boolean;
  schema: DynamicObjectAny;
  operationButton: any[];
  columns?: any[];
  tableButton?: any[];
}

export const useNormalMeta = (formCode: string, needGroup: boolean = true): NormalMetaReturn => {
  const [loading, setLoading] = useState<boolean>(true);
  const [jsonSchema, setJsonSchema] = useState({});
  const [columns, setColumns] = useState([]);
  const [tableButton, setTableButton] = useState([]);

  const [operationButton, setOperationButton] = useState([]);

  const fetchMeta = useCallback(() => {
    getPageMeta(formCode)
      .then(async (res: any) => {
        const { result } = res;
        const { schema, buttons, tableColumns, ArrayTableList, tableButtons } = initialSchema(
          cloneDeep(result),
          'NORMAL',
          needGroup,
        ) as any;

        if (ArrayTableList) {
          await formatForArrayTable(ArrayTableList, schema);
        }
        setTableButton(tableButtons || []);
        setOperationButton(buttons || []);

        setJsonSchema(schema);

        setColumns(tableColumns);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [formCode]);

  useEffect(() => {
    if (formCode) {
      fetchMeta();
    }
  }, [formCode]);

  return {
    loading,
    schema: jsonSchema,
    operationButton,
    columns,
    tableButton
  };
};

export const useDetailMeta = (formCode: string, needGroup: boolean = true): NormalMetaReturn => {
  const [loading, setLoading] = useState<boolean>(false);
  const [jsonSchema, setJsonSchema] = useState({});

  const [operationButton, setOperationButton] = useState([]);

  const fetchMeta = useCallback(() => {
    setLoading(true);

    getPageMeta(formCode)
      .then((res: any) => {
        const { result } = res;
        const { schema, buttons } = initialSchema(cloneDeep(result), 'DETAIL', needGroup) as any;

        setOperationButton(buttons || []);

        setJsonSchema(schema);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [formCode]);

  useEffect(() => {
    if (formCode) {
      fetchMeta();
    }
  }, [formCode]);

  return {
    loading,
    schema: jsonSchema,
    operationButton,
  };
};

export const useGetPageMeta = (formCode?: string): PageMetaConfigData => {
  const [columns, setColumns] = useState<TableColumnProps<any>[]>([]);
  const [jsonSchema, setJsonSchema] = useState({});
  const [loading, setLoading] = useState<boolean>(false);
  useEffect(() => {
    if (formCode) {
      setLoading(true);
      getPageMeta(formCode)
        .then((res: any) => {
          const { result } = res;
          const { tableColumns, schema } = initialSchema(cloneDeep(result), 'SEARCH') as any;
          setJsonSchema(schema);
          setColumns(
            tableColumns?.map((item: any) => {
              const { label, key, columnRenderType } = item;
              const dataIndex = key;
              return {
                dataIndex,
                title: label,
                ellipsis: true,
                render: (text: string, record: any, index: number) =>
                  columnRenderType
                    ? triggerTableCellRender(columnRenderType, {
                        ...record,
                        rowIndex: index,
                      })
                    : text,
              };
            }),
          );
        })
        .finally(() => {
          setLoading(false);
        });
    }
  }, [formCode]);

  return {
    initLoading: loading,
    jsonSchema,
    columns,
  };
};

interface SchemaMetaReturn {
  loading: boolean;
  schema: DynamicObjectAny;
  anchorList: any[];
  operationButton: any[];
  billName: string;
}

export interface DetailApi {
  url: string;
  params: DynamicObjectAny;
  method: string;
}

export const useSchema = (
  pageCode: string,
  billCode: string,
  isEdit?: boolean,
  isDetail?: boolean,
  detailApi?: DetailApi,
): SchemaMetaReturn => {
  const [loading, setLoading] = useState<boolean>(true);
  const [jsonSchema, setJsonSchema] = useState({});

  const [operationButton, setOperationButton] = useState([]);
  const [anchorList, setAnchorList] = useState([]);

  const [billName, setBillName] = useState('');

  const fetchMeta = useCallback(
    (type: initialSchemaType) => {
      const { url, method, params } = detailApi || {};
      getPageMeta(pageCode, url, params, method)
        .then(async (res: any) => {
          const { result } = res;
          const { schema, buttons, ArrayTableList } = initialSchema(cloneDeep(result), type) as any;
          if (ArrayTableList?.length) {
            await formatForArrayTable(ArrayTableList, schema);
          }
          setOperationButton(buttons || []);
          setJsonSchema(schema);

          setAnchorList(result?.group || []);
        })
        .finally(() => {
          setLoading(false);
        });
    },
    [pageCode, detailApi],
  );

  const fetchBillName = () => {
    setBillName('单据名称');
  };

  useEffect(() => {
    if (isEdit || isDetail) {
      if (detailApi) {
        fetchMeta(isDetail ? 'DETAIL' : 'NORMAL');
      }
    } else {
      if (pageCode) {
        fetchMeta('NORMAL');
      }
    }
  }, [pageCode, isDetail, isEdit, detailApi]);

  useEffect(() => {
    if (billCode) {
      fetchBillName();
    }
  }, [billCode]);

  return {
    loading,
    schema: jsonSchema,
    operationButton,
    anchorList,
    billName,
  };
};
